package com.njworkorder.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.njworkorder.DTO.*;
import com.njworkorder.DTO.SelectDTO.SelectCADto;
import com.njworkorder.Entity.*;
import com.njworkorder.Mapper.EqiWithTpMapper;
import com.njworkorder.Service.*;
import com.njworkorder.Utils.Result;
import com.njworkorder.Utils.ResultUtil;
import com.njworkorder.VO.ConstructionAcceptanceListVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Tag(name = "作业管理", description = "作业管理相关接口")
@RestController
@RequestMapping("/JobManagement")
public class JobManagementController {

    private final AssignmentService assignmentService;
    private final AssignmentWithDiseaseService assignmentWithDiseaseService;
    private final EngineeringQualityInfoService engineeringQualityInfoService;
    private final BillOfQuantitiesService billOfQuantitiesService;
    private final BopWithDrService bopWithDrService;
    private final EqiWithDrService eqiWithDrService;
    private final AssignmentApprovalHistoryService assignmentApprovalHistoryService;
    private final EqiWithTpMapper eqiWithTpMapper;
    public JobManagementController(AssignmentService assignmentService, AssignmentWithDiseaseService assignmentWithDiseaseService, EngineeringQualityInfoService engineeringQualityInfoService,
                                   BillOfQuantitiesService billOfQuantitiesService, BopWithDrService bopWithDrService,
                                   EqiWithDrService eqiWithDrService, AssignmentApprovalHistoryService assignmentApprovalHistoryService,
                                   EqiWithTpMapper eqiWithTpMapper) {
        this.assignmentService = assignmentService;
        this.assignmentWithDiseaseService = assignmentWithDiseaseService;
        this.engineeringQualityInfoService = engineeringQualityInfoService;
        this.billOfQuantitiesService = billOfQuantitiesService;
        this.bopWithDrService = bopWithDrService;
        this.eqiWithDrService = eqiWithDrService;
        this.assignmentApprovalHistoryService = assignmentApprovalHistoryService;
        this.eqiWithTpMapper = eqiWithTpMapper;
    }

    @Transactional
    @Operation(summary = "作业管理信息提交")
    @PostMapping("/addOrUpdateDIInfo")
    public Result<String> addDIInfo(@RequestBody JobManagementDto jobManagementDto) {
        List<DiseaseInformationDto> diseaseInformationDtos = jobManagementDto.getDiseaseInformationDtos();//病害和任务管联表
        List<BillOfQuantitiesDto> billOfQuantitiesDto = jobManagementDto.getBillOfQuantitiesDtos();//工程量清单表
        List<EngineeringQualityInfoDto> engineeringQualityInfoDtos = jobManagementDto.getEngineeringQualityInfoDtos();// 工程质量信息表


        List<AssignmentWithDisease> assignmentWithDiseases = new ArrayList<>();
        AssignmentWithDisease assignmentWithDisease;
        for (DiseaseInformationDto item : diseaseInformationDtos){
            assignmentWithDisease = new AssignmentWithDisease();
            BeanUtils.copyProperties(item, assignmentWithDisease);
            assignmentWithDiseases.add(assignmentWithDisease);
        }
        if(!assignmentWithDiseases.isEmpty()){assignmentWithDiseaseService.updateBatchById(assignmentWithDiseases);}


        //工程量清单表
        List<BillOfQuantities> billOfQuantitiesDtos = new ArrayList<>();
        BillOfQuantities billOfQuantities;
        String BoqId;
        String[] diseaseIds;
        LambdaQueryWrapper<BillOfQuantities> queryWrapperBoq = new LambdaQueryWrapper<BillOfQuantities>()
                .select(BillOfQuantities::getId)
                .eq(BillOfQuantities::getJobManagementId, jobManagementDto.getAssignmentId());
        List<String> BoqIds = billOfQuantitiesService.list(queryWrapperBoq).stream().map(BillOfQuantities::getId).toList();
        if(!BoqIds.isEmpty()){
            billOfQuantitiesService.removeByIds(BoqIds);//删除与任务相关工程量清单信息
            LambdaQueryWrapper<BopWithDr> queryWrapper = new LambdaQueryWrapper<BopWithDr>()
                    .in(BopWithDr::getBoqId, BoqIds);
            bopWithDrService.remove(queryWrapper);//删除与任务相关工程量清单关联病害登记信息
        }
        for (BillOfQuantitiesDto item : billOfQuantitiesDto) {
            billOfQuantities = new BillOfQuantities();
            BeanUtils.copyProperties(item, billOfQuantities);
            BoqId = UUID.randomUUID().toString().replace("-", "");
            billOfQuantities.setId(BoqId);
            billOfQuantitiesDtos.add(billOfQuantities);

            diseaseIds = item.getDiseaseIds();
            BopWithDr bopWithDr;
            List<BopWithDr> bopWithDrDtos = new ArrayList<>();
            for (String items : diseaseIds) {
                bopWithDr = new BopWithDr();
                bopWithDr.setBoqId(BoqId);
                bopWithDr.setDiseaseRegistrationId(items);
                bopWithDrDtos.add(bopWithDr);
            }
            bopWithDrService.saveBatch(bopWithDrDtos);
        }
        billOfQuantitiesService.saveBatch(billOfQuantitiesDtos);


        //工程质量信息表
        LambdaQueryWrapper<EngineeringQualityInfo> queryWrapperEqi = new LambdaQueryWrapper<EngineeringQualityInfo>()
                .select(EngineeringQualityInfo::getId)
                .eq(EngineeringQualityInfo::getJobManagementId, jobManagementDto.getAssignmentId());
        List<String> list = engineeringQualityInfoService.list(queryWrapperEqi).stream().map(EngineeringQualityInfo::getId).toList();
        if(!list.isEmpty()) {
            engineeringQualityInfoService.removeByIds(list);//删除与本任务相关工程质量信息
            LambdaQueryWrapper<EqiWithDr> queryWrapperEqiWithDr = new LambdaQueryWrapper<EqiWithDr>()
                    .in(EqiWithDr::getEqiId, list);
            eqiWithDrService.remove(queryWrapperEqiWithDr);//删除工程质量与病害登记关联信息
            LambdaQueryWrapper<EqiWithTp> queryWrapperEqiWithTp = new LambdaQueryWrapper<EqiWithTp>()
                    .in(EqiWithTp::getEqiId, list);
            eqiWithTpMapper.delete(queryWrapperEqiWithTp);//删除实测项目信息与工程质量关联信息
        }
        String EQIId;
        List<EngineeringQualityInfo> EQIList = new ArrayList<>();
        EngineeringQualityInfo engineeringQualityInfo;
        for (EngineeringQualityInfoDto item : engineeringQualityInfoDtos) {
            engineeringQualityInfo = new EngineeringQualityInfo();
            BeanUtils.copyProperties(item, engineeringQualityInfo);
            EQIId = UUID.randomUUID().toString().replace("-", "");
            engineeringQualityInfo.setId(EQIId);
            EQIList.add(engineeringQualityInfo);

            diseaseIds = item.getDiseaseIds();
            EqiWithDr eqiWithDr;
            List<EqiWithDr> eqiWithDrList = new ArrayList<>();
            for (String items : diseaseIds) {
                eqiWithDr = new EqiWithDr();
                eqiWithDr.setEqiId(EQIId);
                eqiWithDr.setDiseaseRegistrationId(items);
                eqiWithDrList.add(eqiWithDr);
            }
            eqiWithDrService.saveBatch(eqiWithDrList);

            if(item.getEqiWithTpDtoList() != null && !item.getEqiWithTpDtoList().isEmpty()){
                List<EqiWithTp> eqiWithTpList = new ArrayList<>();
                EqiWithTp eqiWithTp;
                for (EqiWithTpDto eqiWithTpDto : item.getEqiWithTpDtoList()) {
                    eqiWithTp = new EqiWithTp();
                    BeanUtils.copyProperties(eqiWithTpDto, eqiWithTp);
                    eqiWithTp.setEqiId(EQIId);
                    eqiWithTpList.add(eqiWithTp);
                }
                eqiWithTpMapper.insert(eqiWithTpList);
            }

        }
        engineeringQualityInfoService.saveBatch(EQIList);

        Assignment assignment = getAssignment(jobManagementDto);
        boolean b = assignmentService.updateById(assignment);
        if (b) {
            saveApprovalHistory(jobManagementDto);
            return ResultUtil.success("操作成功");
        }
        return ResultUtil.fail("操作失败");
    }

    private static Assignment getAssignment(JobManagementDto jobManagementDto) {
        Assignment assignment = new Assignment();
        assignment.setId(jobManagementDto.getAssignmentId());
        assignment.setAuditStatus(jobManagementDto.getAuditStatus());
        assignment.setRepairCompletionTime(jobManagementDto.getRepairCompletionTime());
        assignment.setRepairOpinion(jobManagementDto.getRepairOpinion());
        assignment.setInitialReviewTime(jobManagementDto.getInitialReviewTime());
        assignment.setInitialReviewOpinion(jobManagementDto.getInitialReviewOpinion());
        assignment.setFinalJudgmentTime(jobManagementDto.getFinalJudgmentTime());
        assignment.setFinalJudgmentOpinion(jobManagementDto.getFinalJudgmentOpinion());
        return assignment;
    }


    private void saveApprovalHistory(JobManagementDto jobManagementDto) {
        String auditInstructions;
        switch (jobManagementDto.getAuditStatus()) {
            case 4 -> auditInstructions = jobManagementDto.getRepairOpinion();
            case 5, 6 -> auditInstructions = jobManagementDto.getInitialReviewOpinion();
            case 7, 8 -> auditInstructions = jobManagementDto.getFinalJudgmentOpinion();
            default -> {
                return;
            }
        }
        assignmentApprovalHistoryService.saveApprovalHistory(jobManagementDto.getAuditStatus(), auditInstructions, jobManagementDto.getApId(), jobManagementDto.getAssignmentId());
    }



    @Operation(summary = "获取施工验收列表")
    @PostMapping("/getConstructionAcceptanceList")
    public Result<Page<ConstructionAcceptanceListVo>> getConstructionAcceptanceList(@RequestBody SelectCADto selectCADto) {

        MPJLambdaWrapper<Assignment> wrapper = new MPJLambdaWrapper<Assignment>()

                .select("(SELECT count(*) from bill_of_quantities where job_management_id = t.id) AS boqCount")
                .select("(SELECT SUM(nums * unit_price) from bill_of_quantities where job_management_id = t.id) AS TotalAmount")
                .select(Assignment::getId,Assignment::getDiseaseModule)
                .select(DiseaseRegistration::getRoute,DiseaseRegistration::getPosition,DiseaseRegistration::getDirection,DiseaseRegistration::getLane,DiseaseRegistration::getStartPileNum,DiseaseRegistration::getEndPileNum)
                .selectAs(DiseaseRegistration::getEstimatedWorkload,ConstructionAcceptanceListVo::getDrBoq)
                .leftJoin(AdministrativeOrganization.class, AdministrativeOrganization::getId, Assignment::getMaintenanceUnitId,ext ->
                        ext.selectAs(AdministrativeOrganization::getName, ConstructionAcceptanceListVo::getMaintenanceUnitName))
                .leftJoin(AdministrativePersonnel.class, AdministrativePersonnel::getId, Assignment::getConstructionManagerId, ext ->
                        ext.selectAs(AdministrativePersonnel::getName, ConstructionAcceptanceListVo::getConstructionManagerName))

                .leftJoin(AssignmentWithDisease.class, AssignmentWithDisease::getAssignmentId, Assignment::getId, ext ->
                        ext.selectAs(AssignmentWithDisease::getRepairStartTime, ConstructionAcceptanceListVo::getRepairStartTime)
                                .selectAs(AssignmentWithDisease::getEndTimeMaintenance, ConstructionAcceptanceListVo::getEndTimeMaintenance)
                                )
                .leftJoin(DiseaseRegistration.class, DiseaseRegistration::getId, AssignmentWithDisease::getDiseaseId)
                .leftJoin(Dictionary.class,Dictionary::getId,DiseaseRegistration::getDirection,ext ->
                        ext.selectAs(Dictionary::getValusas,ConstructionAcceptanceListVo::getDirectionName))
                .leftJoin(Dictionary.class,Dictionary::getId,DiseaseRegistration::getLane,ext ->
                        ext.selectAs(Dictionary::getValusas,ConstructionAcceptanceListVo::getLaneName))
                .leftJoin(Section.class,Section::getId,DiseaseRegistration::getRoute,ext ->
                        ext.selectAs(Section::getSectionName,ConstructionAcceptanceListVo::getRouteName))
                .leftJoin(InspectionRegistration.class, InspectionRegistration::getId, DiseaseRegistration::getInspectionRegistrationId, ext ->
                        ext.selectAs(InspectionRegistration::getStartPileNumUp, ConstructionAcceptanceListVo::getStartPileNumUp)
                                .selectAs(InspectionRegistration::getStartPileNumDown, ConstructionAcceptanceListVo::getStartPileNumDown)
                                .selectAs(InspectionRegistration::getEndPileNumUp, ConstructionAcceptanceListVo::getEndPileNumUp)
                                .selectAs(InspectionRegistration::getEndPileNumDown, ConstructionAcceptanceListVo::getEndPileNumDown)
                                .selectAs(InspectionRegistration::getInspectionMileage,ConstructionAcceptanceListVo::getInspectionBoq))
                .leftJoin(Disease.class, Disease::getId, DiseaseRegistration::getDisease, ext ->
                        ext.selectAs(Disease::getDiseaseName, ConstructionAcceptanceListVo::getDiseaseName)
                                .selectAs(Disease::getPredictUnit, ConstructionAcceptanceListVo::getPredictUnit))


                .apply("1=1")
                .eq(StringUtils.isNotEmpty(selectCADto.getDiseaseModule()),Assignment::getDiseaseModule,selectCADto.getDiseaseModule())
                .eq(StringUtils.isNotEmpty(selectCADto.getSectionId()),InspectionRegistration::getSectionId,selectCADto.getSectionId())
                .eq(StringUtils.isNotEmpty(selectCADto.getPosition()),DiseaseRegistration::getPosition,selectCADto.getPosition())
                .eq(StringUtils.isNotEmpty(selectCADto.getDiseaseName()),Disease::getDiseaseName,selectCADto.getDiseaseName())
                .eq(selectCADto.getEndTimeMaintenance() != null,AssignmentWithDisease::getEndTimeMaintenance,selectCADto.getEndTimeMaintenance())
                .in(Assignment::getAuditStatus,4,6)
                .groupBy(Assignment::getId)
                .orderByDesc(Assignment::getPublishTime);

        Page<ConstructionAcceptanceListVo> constructionAcceptanceListVoPage = assignmentService.selectJoinListPage(new Page<>(selectCADto.getPageIndex(), selectCADto.getPageSize()), ConstructionAcceptanceListVo.class, wrapper);
        return ResultUtil.success(constructionAcceptanceListVoPage);
    }


//    @Operation(summary = "获取施工确认列表")
//    @PostMapping("/getConstructionConfirmationList")
//    public Result<Page<ConstructionConfirmationVo>> getConstructionConfirmation(@RequestBody SelectCADto selectCADto){
//
//        MPJLambdaWrapper<Assignment> wrapper = new MPJLambdaWrapper<Assignment>()
//                .select(Assignment::getId,Assignment::getDiseaseModule,Assignment::getTaskOrderNumber,Assignment::getAuditStatus,Assignment::getDispatchDate)
//
//                .select(DiseaseRegistration::getRoute,DiseaseRegistration::getPosition,DiseaseRegistration::getDirection,DiseaseRegistration::getLane,DiseaseRegistration::getStartPileNum,DiseaseRegistration::getEndPileNum)
//
//                .leftJoin(AdministrativeOrganization.class, AdministrativeOrganization::getId, Assignment::getMaintenanceUnitId,ext ->
//                        ext.selectAs(AdministrativeOrganization::getName, ConstructionConfirmationVo::getMaintenanceUnitName))
//                .leftJoin(AdministrativePersonnel.class, AdministrativePersonnel::getId, Assignment::getConstructionManagerId,ext ->
//                        ext.selectAs(AdministrativePersonnel::getName, ConstructionConfirmationVo::getConstructionManagerName))
//                .leftJoin(AdministrativePersonnel.class, AdministrativePersonnel::getId, Assignment::getDispatchPersonId,ext ->
//                        ext.selectAs(AdministrativePersonnel::getName, ConstructionConfirmationVo::getDispatchPersonName))
//
//                .leftJoin(AssignmentWithDisease.class, AssignmentWithDisease::getAssignmentId, Assignment::getId)
//                .leftJoin(DiseaseRegistration.class, DiseaseRegistration::getId, AssignmentWithDisease::getDiseaseId)
//
//                .leftJoin(Section.class,Section::getId,DiseaseRegistration::getRoute,ext ->
//                        ext.selectAs(Section::getSectionName, ConstructionConfirmationVo::getRouteName))
//                .leftJoin(Dictionary.class,Dictionary::getId,DiseaseRegistration::getDirection,ext ->
//                        ext.selectAs(Dictionary::getValusas,ConstructionConfirmationVo::getDirectionName))
//                .leftJoin(Dictionary.class,Dictionary::getId,DiseaseRegistration::getLane,ext ->
//                        ext.selectAs(Dictionary::getValusas,ConstructionConfirmationVo::getLaneName))
//
//
//                .apply("1=1")
//
//                .eq(StringUtils.isNotEmpty(selectCADto.getDiseaseModule()),Assignment::getDiseaseModule,selectCADto.getDiseaseModule())
//                .eq(StringUtils.isNotEmpty(selectCADto.getSectionId()),InspectionRegistration::getSectionId,selectCADto.getSectionId())
//                .eq(StringUtils.isNotEmpty(selectCADto.getPosition()),DiseaseRegistration::getPosition,selectCADto.getPosition())
//                .eq(StringUtils.isNotEmpty(selectCADto.getDiseaseName()),Disease::getDiseaseName,selectCADto.getDiseaseName())
//                .eq(selectCADto.getEndTimeMaintenance() != null,AssignmentWithDisease::getEndTimeMaintenance,selectCADto.getEndTimeMaintenance())
//                .in(Assignment::getAuditStatus,5,7,8)
//                .groupBy(Assignment::getId)
//                .orderByDesc(Assignment::getPublishTime);
//
//        Page<ConstructionConfirmationVo> constructionAcceptanceListVoPage = assignmentService.selectJoinListPage(new Page<>(selectCADto.getPageIndex(), selectCADto.getPageSize()), ConstructionConfirmationVo.class, wrapper);
//        return ResultUtil.success(constructionAcceptanceListVoPage);
//    }



    @Operation(summary = "获取施工确认列表")
    @PostMapping("/getConstructionConfirmationList")
    public Result<Page<ConstructionAcceptanceListVo>> getConstructionConfirmationList(@RequestBody SelectCADto selectCADto) {

        MPJLambdaWrapper<Assignment> wrapper = new MPJLambdaWrapper<Assignment>()

                .select("(SELECT count(*) from bill_of_quantities where job_management_id = t.id) AS boqCount")
                .select("(SELECT SUM(nums * unit_price) from bill_of_quantities where job_management_id = t.id) AS TotalAmount")
                .select(Assignment::getId,Assignment::getDiseaseModule)
                .select(DiseaseRegistration::getRoute,DiseaseRegistration::getPosition,DiseaseRegistration::getDirection,DiseaseRegistration::getLane,DiseaseRegistration::getStartPileNum,DiseaseRegistration::getEndPileNum)
                .selectAs(DiseaseRegistration::getEstimatedWorkload,ConstructionAcceptanceListVo::getDrBoq)
                .leftJoin(AdministrativeOrganization.class, AdministrativeOrganization::getId, Assignment::getMaintenanceUnitId,ext ->
                        ext.selectAs(AdministrativeOrganization::getName, ConstructionAcceptanceListVo::getMaintenanceUnitName))
                .leftJoin(AdministrativePersonnel.class, AdministrativePersonnel::getId, Assignment::getConstructionManagerId, ext ->
                        ext.selectAs(AdministrativePersonnel::getName, ConstructionAcceptanceListVo::getConstructionManagerName))

                .leftJoin(AssignmentWithDisease.class, AssignmentWithDisease::getAssignmentId, Assignment::getId, ext ->
                        ext.selectAs(AssignmentWithDisease::getRepairStartTime, ConstructionAcceptanceListVo::getRepairStartTime)
                                .selectAs(AssignmentWithDisease::getEndTimeMaintenance, ConstructionAcceptanceListVo::getEndTimeMaintenance)
                )
                .leftJoin(DiseaseRegistration.class, DiseaseRegistration::getId, AssignmentWithDisease::getDiseaseId)
                .leftJoin(Dictionary.class,Dictionary::getId,DiseaseRegistration::getDirection,ext ->
                        ext.selectAs(Dictionary::getValusas,ConstructionAcceptanceListVo::getDirectionName))
                .leftJoin(Dictionary.class,Dictionary::getId,DiseaseRegistration::getLane,ext ->
                        ext.selectAs(Dictionary::getValusas,ConstructionAcceptanceListVo::getLaneName))
                .leftJoin(Section.class,Section::getId,DiseaseRegistration::getRoute,ext ->
                        ext.selectAs(Section::getSectionName,ConstructionAcceptanceListVo::getRouteName))
                .leftJoin(InspectionRegistration.class, InspectionRegistration::getId, DiseaseRegistration::getInspectionRegistrationId, ext ->
                        ext.selectAs(InspectionRegistration::getStartPileNumUp, ConstructionAcceptanceListVo::getStartPileNumUp)
                                .selectAs(InspectionRegistration::getStartPileNumDown, ConstructionAcceptanceListVo::getStartPileNumDown)
                                .selectAs(InspectionRegistration::getEndPileNumUp, ConstructionAcceptanceListVo::getEndPileNumUp)
                                .selectAs(InspectionRegistration::getEndPileNumDown, ConstructionAcceptanceListVo::getEndPileNumDown)
                                .selectAs(InspectionRegistration::getInspectionMileage,ConstructionAcceptanceListVo::getInspectionBoq))
                .leftJoin(Disease.class, Disease::getId, DiseaseRegistration::getDisease, ext ->
                        ext.selectAs(Disease::getDiseaseName, ConstructionAcceptanceListVo::getDiseaseName)
                                .selectAs(Disease::getPredictUnit, ConstructionAcceptanceListVo::getPredictUnit))


                .apply("1=1")
                .eq(StringUtils.isNotEmpty(selectCADto.getDiseaseModule()),Assignment::getDiseaseModule,selectCADto.getDiseaseModule())
                .eq(StringUtils.isNotEmpty(selectCADto.getSectionId()),InspectionRegistration::getSectionId,selectCADto.getSectionId())
                .eq(StringUtils.isNotEmpty(selectCADto.getPosition()),DiseaseRegistration::getPosition,selectCADto.getPosition())
                .eq(StringUtils.isNotEmpty(selectCADto.getDiseaseName()),Disease::getDiseaseName,selectCADto.getDiseaseName())
                .eq(selectCADto.getEndTimeMaintenance() != null,AssignmentWithDisease::getEndTimeMaintenance,selectCADto.getEndTimeMaintenance())
                .in(Assignment::getAuditStatus,5,7,8)
                .groupBy(Assignment::getId)
                .orderByDesc(Assignment::getPublishTime);

        Page<ConstructionAcceptanceListVo> constructionAcceptanceListVoPage = assignmentService.selectJoinListPage(new Page<>(selectCADto.getPageIndex(), selectCADto.getPageSize()), ConstructionAcceptanceListVo.class, wrapper);
        return ResultUtil.success(constructionAcceptanceListVoPage);
    }


}
